﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Serial;

namespace HslCommunication.Instrument.DLT
{
	/// <summary>
	/// 基于多功能电能表通信协议实现的通讯类，参考的文档是DLT645-2007，主要实现了对电表数据的读取和一些功能方法，
	/// 在点对点模式下，需要在打开串口后调用 <see cref="M:HslCommunication.Instrument.DLT.DLT645.ReadAddress" /> 方法，数据标识格式为 00-00-00-00，具体参照文档手册。<br />
	/// The communication type based on the communication protocol of the multifunctional electric energy meter. 
	/// The reference document is DLT645-2007, which mainly realizes the reading of the electric meter data and some functional methods. 
	/// In the point-to-point mode, you need to call <see cref="M:HslCommunication.Instrument.DLT.DLT645.ReadAddress" /> method after opening the serial port.
	/// the data identification format is 00-00-00-00, refer to the documentation manual for details.
	/// </summary>
	/// <remarks>
	/// 如果一对多的模式，地址可以携带地址域访问，例如 "s=2;00-00-00-00"，主要使用 <see cref="M:HslCommunication.Instrument.DLT.DLT645.ReadDouble(System.String,System.UInt16)" /> 方法来读取浮点数，
	/// <see cref="M:HslCommunication.Serial.SerialDeviceBase.ReadString(System.String,System.UInt16)" /> 方法来读取字符串
	/// </remarks>
	/// <example>
	/// 具体的地址请参考相关的手册内容，如果没有，可以联系HSL作者或者，下面列举一些常用的地址<br />
	/// 对于电能来说，DI0是结算日的信息，现在的就是写0，上一结算日的就写 01，上12结算日就写 0C
	/// <list type="table">
	///   <listheader>
	///     <term>DI3</term>
	///     <term>DI2</term>
	///     <term>DI1</term>
	///     <term>DI0</term>
	///     <term>地址示例</term>
	///     <term>读取方式</term>
	///     <term>数据项名称</term>
	///     <term>备注</term>
	///   </listheader>
	///   <item>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00-00-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>（当前）组合有功总电能(kwh)</term>
	///     <term>00-00-01-00到00-00-3F-00分别是组合有功费率1~63电能</term>
	///   </item>
	///   <item>
	///     <term>00</term>
	///     <term>01</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00-01-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>（当前）正向有功总电能(kwh)</term>
	///     <term>00-01-01-00到00-01-3F-00分别是正向有功费率1~63电能</term>
	///   </item>
	///   <item>
	///     <term>00</term>
	///     <term>02</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00-02-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>（当前）反向有功总电能(kwh)</term>
	///     <term>00-02-01-00到00-02-3F-00分别是反向有功费率1~63电能</term>
	///   </item>
	///   <item>
	///     <term>00</term>
	///     <term>03</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00-03-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>（当前）组合无功总电能(kvarh)</term>
	///     <term>00-03-01-00到00-03-3F-00分别是组合无功费率1~63电能</term>
	///   </item>
	///   <item>
	///     <term>00</term>
	///     <term>09</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00-09-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>（当前）正向视在总电能(kvah)</term>
	///     <term>00-09-01-00到00-09-3F-00分别是正向视在费率1~63电能</term>
	///   </item>
	///   <item>
	///     <term>00</term>
	///     <term>0A</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>00-0A-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>（当前）反向视在总电能(kvah)</term>
	///     <term>00-0A-01-00到00-0A-3F-00分别是反向视在费率1~63电能</term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>01</term>
	///     <term>01</term>
	///     <term>00</term>
	///     <term>02-01-01-00</term>
	///     <term>ReadDouble</term>
	///     <term>A相电压(V)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>01</term>
	///     <term>02</term>
	///     <term>00</term>
	///     <term>02-01-02-00</term>
	///     <term>ReadDouble</term>
	///     <term>B相电压(V)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>01</term>
	///     <term>03</term>
	///     <term>00</term>
	///     <term>02-01-03-00</term>
	///     <term>ReadDouble</term>
	///     <term>C相电压(V)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>02</term>
	///     <term>01</term>
	///     <term>00</term>
	///     <term>02-02-01-00</term>
	///     <term>ReadDouble</term>
	///     <term>A相电流(A)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>02</term>
	///     <term>02</term>
	///     <term>00</term>
	///     <term>02-02-02-00</term>
	///     <term>ReadDouble</term>
	///     <term>B相电流(A)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>02</term>
	///     <term>03</term>
	///     <term>00</term>
	///     <term>02-02-03-00</term>
	///     <term>ReadDouble</term>
	///     <term>C相电流(A)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>03</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>02-03-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>瞬时总有功功率(kw)</term>
	///     <term>DI1=1时表示A相，2时表示B相，3时表示C相</term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>04</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>02-04-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>瞬时总无功功率(kvar)</term>
	///     <term>DI1=1时表示A相，2时表示B相，3时表示C相</term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>05</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>02-05-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>瞬时总视在功率(kva)</term>
	///     <term>DI1=1时表示A相，2时表示B相，3时表示C相</term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>06</term>
	///     <term>00</term>
	///     <term>00</term>
	///     <term>02-06-00-00</term>
	///     <term>ReadDouble</term>
	///     <term>总功率因素</term>
	///     <term>DI1=1时表示A相，2时表示B相，3时表示C相</term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>07</term>
	///     <term>01</term>
	///     <term>00</term>
	///     <term>02-07-01-00</term>
	///     <term>ReadDouble</term>
	///     <term>A相相角(°)</term>
	///     <term>DI1=1时表示A相，2时表示B相，3时表示C相</term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>08</term>
	///     <term>01</term>
	///     <term>00</term>
	///     <term>02-08-01-00</term>
	///     <term>ReadDouble</term>
	///     <term>A相电压波形失真度(%)</term>
	///     <term>DI1=1时表示A相，2时表示B相，3时表示C相</term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>01</term>
	///     <term>02-80-00-01</term>
	///     <term>ReadDouble</term>
	///     <term>零线电流(A)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>02</term>
	///     <term>02-80-00-02</term>
	///     <term>ReadDouble</term>
	///     <term>电网频率(HZ)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>03</term>
	///     <term>02-80-00-03</term>
	///     <term>ReadDouble</term>
	///     <term>一分钟有功总平均功率(kw)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>04</term>
	///     <term>02-80-00-04</term>
	///     <term>ReadDouble</term>
	///     <term>当前有功需量(kw)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>05</term>
	///     <term>02-80-00-05</term>
	///     <term>ReadDouble</term>
	///     <term>当前无功需量(kvar)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>06</term>
	///     <term>02-80-00-06</term>
	///     <term>ReadDouble</term>
	///     <term>当前视在需量(kva)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>07</term>
	///     <term>02-80-00-07</term>
	///     <term>ReadDouble</term>
	///     <term>表内温度(摄氏度)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>08</term>
	///     <term>02-80-00-08</term>
	///     <term>ReadDouble</term>
	///     <term>时钟电池电压(V)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>09</term>
	///     <term>02-80-00-09</term>
	///     <term>ReadDouble</term>
	///     <term>停电抄表电池电压(V)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>02</term>
	///     <term>80</term>
	///     <term>00</term>
	///     <term>0A</term>
	///     <term>02-80-00-0A</term>
	///     <term>ReadDouble</term>
	///     <term>内部电池工作时间(分钟)</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>04</term>
	///     <term>00</term>
	///     <term>04</term>
	///     <term>03</term>
	///     <term>04-00-04-03</term>
	///     <term>ReadString("04-00-04-03", 32)</term>
	///     <term>资产管理编码</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>04</term>
	///     <term>00</term>
	///     <term>04</term>
	///     <term>0B</term>
	///     <term>04-00-04-0B</term>
	///     <term>ReadString("04-00-04-0B", 10)</term>
	///     <term>电表型号</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>04</term>
	///     <term>00</term>
	///     <term>04</term>
	///     <term>0C</term>
	///     <term>04-00-04-0C</term>
	///     <term>ReadString("04-00-04-0C", 10)</term>
	///     <term>生产日期</term>
	///     <term></term>
	///   </item>
	/// </list>
	/// 直接串口初始化，打开串口，就可以对数据进行读取了，地址如上图所示。
	/// </example>
	// Token: 0x020000EC RID: 236
	public class DLT645 : SerialDeviceBase
	{
		/// <summary>
		/// 指定地址域，密码，操作者代码来实例化一个对象<br />
		/// Get or set the current address domain information, which is a 12-character BCD code, for example: 149100007290
		/// </summary>
		/// <param name="station">设备的站号信息</param>
		/// <param name="password">密码，写入的时候进行验证的信息</param>
		/// <param name="opCode">操作者代码</param>
		// Token: 0x0600140E RID: 5134 RVA: 0x0006749C File Offset: 0x0006569C
		public DLT645(string station, string password = "", string opCode = "")
		{
			base.ByteTransform = new RegularByteTransform();
			this.station = station;
			this.password = (string.IsNullOrEmpty(password) ? "00000000" : password);
			this.opCode = (string.IsNullOrEmpty(opCode) ? "00000000" : opCode);
		}

		/// <summary>
		/// 激活设备的命令，只发送数据到设备，不等待设备数据返回<br />
		/// The command to activate the device, only send data to the device, do not wait for the device data to return
		/// </summary>
		/// <returns>是否发送成功</returns>
		// Token: 0x0600140F RID: 5135 RVA: 0x00067511 File Offset: 0x00065711
		public OperateResult ActiveDeveice()
		{
			return base.ReadBase(new byte[]
			{
				254,
				254,
				254,
				254
			}, true);
		}

		// Token: 0x06001410 RID: 5136 RVA: 0x0006752C File Offset: 0x0006572C
		private OperateResult<byte[]> ReadWithAddress(string address, byte[] dataArea)
		{
			OperateResult<byte[]> operateResult = DLT645.BuildEntireCommand(address, 17, dataArea);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult operateResult3 = DLT645.CheckResponse(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
					}
					else
					{
						bool flag4 = operateResult2.Content.Length < 16;
						if (flag4)
						{
							result = OperateResult.CreateSuccessResult<byte[]>(new byte[0]);
						}
						else
						{
							result = OperateResult.CreateSuccessResult<byte[]>(operateResult2.Content.SelectMiddle(14, operateResult2.Content.Length - 16));
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 根据指定的数据标识来读取相关的原始数据信息，地址标识根据手册来，从高位到地位，例如 00-00-00-00，分割符可以任意特殊字符或是没有分隔符。<br />
		/// Read the relevant original data information according to the specified data identifier. The address identifier is based on the manual, 
		/// from high to position, such as 00-00-00-00. The separator can be any special character or no separator.
		/// </summary>
		/// <remarks>
		/// 地址可以携带地址域信息，例如 "s=2;00-00-00-00" 或是 "s=100000;00-00-02-00"，关于数据域信息，需要查找手册，例如:00-01-00-00 表示： (当前)正向有功总电能
		/// </remarks>
		/// <param name="address">数据标识，具体需要查找手册来对应</param>
		/// <param name="length">数据长度信息</param>
		/// <returns>结果信息</returns>
		// Token: 0x06001411 RID: 5137 RVA: 0x000675E4 File Offset: 0x000657E4
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<string, byte[]> operateResult = DLT645.AnalysisBytesAddress(address, this.station, length);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				result = this.ReadWithAddress(operateResult.Content1, operateResult.Content2);
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x06001412 RID: 5138 RVA: 0x0006762C File Offset: 0x0006582C
		public override OperateResult<double[]> ReadDouble(string address, ushort length)
		{
			OperateResult<string, byte[]> operateResult = DLT645.AnalysisBytesAddress(address, this.station, length);
			bool flag = !operateResult.IsSuccess;
			OperateResult<double[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<double[]>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = this.ReadWithAddress(operateResult.Content1, operateResult.Content2);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<double[]>(operateResult2);
				}
				else
				{
					result = DLTTransform.TransDoubleFromDLt(operateResult2.Content, length, DLT645.GetFormatWithDataArea(operateResult.Content2));
				}
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x06001413 RID: 5139 RVA: 0x000676A4 File Offset: 0x000658A4
		public override OperateResult<string> ReadString(string address, ushort length, Encoding encoding)
		{
			OperateResult<byte[]> operateResult = this.Read(address, 1);
			bool flag = !operateResult.IsSuccess;
			OperateResult<string> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				result = DLTTransform.TransStringFromDLt(operateResult.Content, length);
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Instrument.DLT.DLT645.ReadDouble(System.String,System.UInt16)" />
		// Token: 0x06001414 RID: 5140 RVA: 0x000676E4 File Offset: 0x000658E4
		[DebuggerStepThrough]
		public override Task<OperateResult<double[]>> ReadDoubleAsync(string address, ushort length)
		{
			DLT645.<ReadDoubleAsync>d__6 <ReadDoubleAsync>d__ = new DLT645.<ReadDoubleAsync>d__6();
			<ReadDoubleAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<double[]>>.Create();
			<ReadDoubleAsync>d__.<>4__this = this;
			<ReadDoubleAsync>d__.address = address;
			<ReadDoubleAsync>d__.length = length;
			<ReadDoubleAsync>d__.<>1__state = -1;
			<ReadDoubleAsync>d__.<>t__builder.Start<DLT645.<ReadDoubleAsync>d__6>(ref <ReadDoubleAsync>d__);
			return <ReadDoubleAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc />
		// Token: 0x06001415 RID: 5141 RVA: 0x00067738 File Offset: 0x00065938
		[DebuggerStepThrough]
		public override Task<OperateResult<string>> ReadStringAsync(string address, ushort length, Encoding encoding)
		{
			DLT645.<ReadStringAsync>d__7 <ReadStringAsync>d__ = new DLT645.<ReadStringAsync>d__7();
			<ReadStringAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<string>>.Create();
			<ReadStringAsync>d__.<>4__this = this;
			<ReadStringAsync>d__.address = address;
			<ReadStringAsync>d__.length = length;
			<ReadStringAsync>d__.encoding = encoding;
			<ReadStringAsync>d__.<>1__state = -1;
			<ReadStringAsync>d__.<>t__builder.Start<DLT645.<ReadStringAsync>d__7>(ref <ReadStringAsync>d__);
			return <ReadStringAsync>d__.<>t__builder.Task;
		}

		/// <summary>
		/// 根据指定的数据标识来写入相关的原始数据信息，地址标识根据手册来，从高位到地位，例如 00-00-00-00，分割符可以任意特殊字符或是没有分隔符。<br />
		/// Read the relevant original data information according to the specified data identifier. The address identifier is based on the manual, 
		/// from high to position, such as 00-00-00-00. The separator can be any special character or no separator.
		/// </summary>
		/// <remarks>
		/// 地址可以携带地址域信息，例如 "s=2;00-00-00-00" 或是 "s=100000;00-00-02-00"，关于数据域信息，需要查找手册，例如:00-01-00-00 表示： (当前)正向有功总电能<br />
		/// 注意：本命令必须与编程键配合使用
		/// </remarks>
		/// <param name="address">地址信息</param>
		/// <param name="value">写入的数据值</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06001416 RID: 5142 RVA: 0x00067794 File Offset: 0x00065994
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<string, byte[]> operateResult = DLT645.AnalysisBytesAddress(address, this.station, 1);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				byte[] dataArea = SoftBasic.SpliceArray<byte>(new byte[][]
				{
					operateResult.Content2,
					this.password.ToHexBytes(),
					this.opCode.ToHexBytes(),
					value
				});
				OperateResult<byte[]> operateResult2 = DLT645.BuildEntireCommand(operateResult.Content1, 21, dataArea);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult<byte[]> operateResult3 = base.ReadBase(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						result = DLT645.CheckResponse(operateResult3.Content);
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 读取设备的通信地址，仅支持点对点通讯的情况，返回地址域数据，例如：149100007290<br />
		/// Read the communication address of the device, only support point-to-point communication, and return the address field data, for example: 149100007290
		/// </summary>
		/// <returns>设备的通信地址</returns>
		// Token: 0x06001417 RID: 5143 RVA: 0x00067858 File Offset: 0x00065A58
		public OperateResult<string> ReadAddress()
		{
			OperateResult<byte[]> operateResult = DLT645.BuildEntireCommand("AAAAAAAAAAAA", 19, null);
			bool flag = !operateResult.IsSuccess;
			OperateResult<string> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<string>(operateResult2);
				}
				else
				{
					OperateResult operateResult3 = DLT645.CheckResponse(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<string>(operateResult3);
					}
					else
					{
						this.station = Enumerable.ToArray<byte>(Enumerable.Reverse<byte>(operateResult2.Content.SelectMiddle(1, 6))).ToHexString();
						result = OperateResult.CreateSuccessResult<string>(Enumerable.ToArray<byte>(Enumerable.Reverse<byte>(operateResult2.Content.SelectMiddle(1, 6))).ToHexString());
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 写入设备的地址域信息，仅支持点对点通讯的情况，需要指定地址域信息，例如：149100007290<br />
		/// Write the address domain information of the device, only support point-to-point communication, 
		/// you need to specify the address domain information, for example: 149100007290
		/// </summary>
		/// <param name="address">等待写入的地址域</param>
		/// <returns>是否写入成功</returns>
		// Token: 0x06001418 RID: 5144 RVA: 0x00067924 File Offset: 0x00065B24
		public OperateResult WriteAddress(string address)
		{
			OperateResult<byte[]> addressByteFromString = DLT645.GetAddressByteFromString(address);
			bool flag = !addressByteFromString.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = addressByteFromString;
			}
			else
			{
				OperateResult<byte[]> operateResult = DLT645.BuildEntireCommand("AAAAAAAAAAAA", 21, addressByteFromString.Content);
				bool flag2 = !operateResult.IsSuccess;
				if (flag2)
				{
					result = operateResult;
				}
				else
				{
					OperateResult<byte[]> operateResult2 = base.ReadBase(operateResult.Content);
					bool flag3 = !operateResult2.IsSuccess;
					if (flag3)
					{
						result = operateResult2;
					}
					else
					{
						OperateResult operateResult3 = DLT645.CheckResponse(operateResult2.Content);
						bool flag4 = !operateResult3.IsSuccess;
						if (flag4)
						{
							result = operateResult3;
						}
						else
						{
							bool flag5 = SoftBasic.IsTwoBytesEquel(operateResult2.Content.SelectMiddle(1, 6), DLT645.GetAddressByteFromString(address).Content);
							if (flag5)
							{
								result = OperateResult.CreateSuccessResult();
							}
							else
							{
								result = new OperateResult(StringResources.Language.DLTErrorWriteReadCheckFailed);
							}
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 广播指定的时间，强制从站与主站时间同步，传入<see cref="T:System.DateTime" />时间对象，没有数据返回。<br />
		/// Broadcast the specified time, force the slave station to synchronize with the master station time, 
		/// pass in the <see cref="T:System.DateTime" /> time object, and no data will be returned.
		/// </summary>
		/// <param name="dateTime">时间对象</param>
		/// <returns>是否成功</returns>
		// Token: 0x06001419 RID: 5145 RVA: 0x000679FC File Offset: 0x00065BFC
		public OperateResult BroadcastTime(DateTime dateTime)
		{
			string value = string.Format("{0:D2}{1:D2}{2:D2}{3:D2}{4:D2}{5:D2}", new object[]
			{
				dateTime.Second,
				dateTime.Minute,
				dateTime.Hour,
				dateTime.Day,
				dateTime.Month,
				dateTime.Year % 100
			});
			OperateResult<byte[]> operateResult = DLT645.BuildEntireCommand("999999999999", 8, value.ToHexBytes());
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				result = base.ReadBase(operateResult.Content, true);
			}
			return result;
		}

		/// <summary>
		/// 对设备发送冻结命令，默认点对点操作，地址域为 99999999999999 时为广播，数据域格式说明：MMDDhhmm(月日时分)，
		/// 99DDhhmm表示月为周期定时冻结，9999hhmm表示日为周期定时冻结，999999mm表示以小时为周期定时冻结，99999999表示瞬时冻结<br />
		/// Send a freeze command to the device, the default point-to-point operation, when the address field is 9999999999999, 
		/// it is broadcast, and the data field format description: MMDDhhmm (month, day, hour and minute), 
		/// 99DDhhmm means the month is the periodic fixed freeze, 9999hhmm means the day is the periodic periodic freeze, 
		/// and 999999mm means the hour It is periodic timed freezing, 99999999 means instantaneous freezing
		/// </summary>
		/// <param name="dataArea">数据域信息</param>
		/// <returns>是否成功冻结</returns>
		// Token: 0x0600141A RID: 5146 RVA: 0x00067AAC File Offset: 0x00065CAC
		public OperateResult FreezeCommand(string dataArea)
		{
			OperateResult<string, byte[]> operateResult = DLT645.AnalysisBytesAddress(dataArea, this.station, 1);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = DLT645.BuildEntireCommand(operateResult.Content1, 22, operateResult.Content2);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					bool flag3 = operateResult.Content1 == "999999999999";
					if (flag3)
					{
						result = base.ReadBase(operateResult2.Content, true);
					}
					else
					{
						OperateResult<byte[]> operateResult3 = base.ReadBase(operateResult2.Content);
						bool flag4 = !operateResult3.IsSuccess;
						if (flag4)
						{
							result = operateResult3;
						}
						else
						{
							result = DLT645.CheckResponse(operateResult3.Content);
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 更改通信速率，波特率可选 600,1200,2400,4800,9600,19200，其他值无效，可以携带地址域信息，s=1;9600 <br />
		/// Change the communication rate, the baud rate can be 600, 1200, 2400, 4800, 9600, 19200, 
		/// other values are invalid, you can carry address domain information, s=1;9600
		/// </summary>
		/// <param name="baudRate">波特率的信息</param>
		/// <returns>是否更改成功</returns>
		// Token: 0x0600141B RID: 5147 RVA: 0x00067B64 File Offset: 0x00065D64
		public OperateResult ChangeBaudRate(string baudRate)
		{
			OperateResult<string, int> operateResult = DLT645.AnalysisIntegerAddress(baudRate, this.station);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				int content = operateResult.Content2;
				int num = content;
				byte b;
				if (num <= 2400)
				{
					if (num == 600)
					{
						b = 2;
						goto IL_AF;
					}
					if (num == 1200)
					{
						b = 4;
						goto IL_AF;
					}
					if (num == 2400)
					{
						b = 8;
						goto IL_AF;
					}
				}
				else
				{
					if (num == 4800)
					{
						b = 16;
						goto IL_AF;
					}
					if (num == 9600)
					{
						b = 32;
						goto IL_AF;
					}
					if (num == 19200)
					{
						b = 64;
						goto IL_AF;
					}
				}
				return new OperateResult(StringResources.Language.NotSupportedFunction);
				IL_AF:
				OperateResult<byte[]> operateResult2 = DLT645.BuildEntireCommand(operateResult.Content1, 23, new byte[]
				{
					b
				});
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult<byte[]> operateResult3 = base.ReadBase(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						OperateResult operateResult4 = DLT645.CheckResponse(operateResult3.Content);
						bool flag4 = !operateResult4.IsSuccess;
						if (flag4)
						{
							result = operateResult4;
						}
						else
						{
							bool flag5 = operateResult3.Content[10] == b;
							if (flag5)
							{
								result = OperateResult.CreateSuccessResult();
							}
							else
							{
								result = new OperateResult(StringResources.Language.DLTErrorWriteReadCheckFailed);
							}
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 获取或设置当前的地址域信息，是一个12个字符的BCD码，例如：149100007290<br />
		/// Get or set the current address domain information, which is a 12-character BCD code, for example: 149100007290
		/// </summary>
		// Token: 0x170004DE RID: 1246
		// (get) Token: 0x0600141C RID: 5148 RVA: 0x00067CC0 File Offset: 0x00065EC0
		// (set) Token: 0x0600141D RID: 5149 RVA: 0x00067CC8 File Offset: 0x00065EC8
		public string Station
		{
			get
			{
				return this.station;
			}
			set
			{
				this.station = value;
			}
		}

		/// <inheritdoc />
		// Token: 0x0600141E RID: 5150 RVA: 0x00067CD1 File Offset: 0x00065ED1
		public override string ToString()
		{
			return string.Format("DLT645[{0}:{1}]", base.PortName, base.BaudRate);
		}

		/// <summary>
		/// 将地址解析成BCD码的地址，并且扩充到12位，不够的补0操作
		/// </summary>
		/// <param name="address">地址域信息</param>
		/// <returns>实际的结果</returns>
		// Token: 0x0600141F RID: 5151 RVA: 0x00067CF0 File Offset: 0x00065EF0
		public static OperateResult<byte[]> GetAddressByteFromString(string address)
		{
			bool flag = address == null || address.Length == 0;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = new OperateResult<byte[]>(StringResources.Language.DLTAddressCannotNull);
			}
			else
			{
				bool flag2 = address.Length > 12;
				if (flag2)
				{
					result = new OperateResult<byte[]>(StringResources.Language.DLTAddressCannotMoreThan12);
				}
				else
				{
					bool flag3 = !Regex.IsMatch(address, "^[0-9A-A]+$");
					if (flag3)
					{
						result = new OperateResult<byte[]>(StringResources.Language.DLTAddressMatchFailed);
					}
					else
					{
						bool flag4 = address.Length < 12;
						if (flag4)
						{
							address = address.PadLeft(12, '0');
						}
						result = OperateResult.CreateSuccessResult<byte[]>(Enumerable.ToArray<byte>(Enumerable.Reverse<byte>(address.ToHexBytes())));
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 将指定的地址信息，控制码信息，数据域信息打包成完整的报文命令
		/// </summary>
		/// <param name="address">地址域信息，地址域由6个字节构成，每字节2位BCD码，地址长度可达12位十进制数。地址域支持锁位寻址，即从若干低位起，剩余高位补AAH作为通配符进行读表操作</param>
		/// <param name="control">控制码信息</param>
		/// <param name="dataArea">数据域的内容</param>
		/// <returns>返回是否报文创建成功</returns>
		// Token: 0x06001420 RID: 5152 RVA: 0x00067D9C File Offset: 0x00065F9C
		public static OperateResult<byte[]> BuildEntireCommand(string address, byte control, byte[] dataArea)
		{
			bool flag = dataArea == null;
			if (flag)
			{
				dataArea = new byte[0];
			}
			OperateResult<byte[]> addressByteFromString = DLT645.GetAddressByteFromString(address);
			bool flag2 = !addressByteFromString.IsSuccess;
			OperateResult<byte[]> result;
			if (flag2)
			{
				result = addressByteFromString;
			}
			else
			{
				byte[] array = new byte[12 + dataArea.Length];
				array[0] = 104;
				addressByteFromString.Content.CopyTo(array, 1);
				array[7] = 104;
				array[8] = control;
				array[9] = (byte)dataArea.Length;
				bool flag3 = dataArea.Length != 0;
				if (flag3)
				{
					dataArea.CopyTo(array, 10);
					for (int i = 0; i < dataArea.Length; i++)
					{
						byte[] array2 = array;
						int num = i + 10;
						array2[num] += 51;
					}
				}
				int num2 = 0;
				for (int j = 0; j < array.Length - 2; j++)
				{
					num2 += (int)array[j];
				}
				array[array.Length - 2] = (byte)num2;
				array[array.Length - 1] = 22;
				result = OperateResult.CreateSuccessResult<byte[]>(array);
			}
			return result;
		}

		/// <summary>
		/// 从用户输入的地址信息中解析出真实的地址及数据标识
		/// </summary>
		/// <param name="address">用户输入的地址信息</param>
		/// <param name="defaultStation">默认的地址域</param>
		/// <param name="length">数据长度信息</param>
		/// <returns>解析结果信息</returns>
		// Token: 0x06001421 RID: 5153 RVA: 0x00067E90 File Offset: 0x00066090
		public static OperateResult<string, byte[]> AnalysisBytesAddress(string address, string defaultStation, ushort length = 1)
		{
			string value = defaultStation;
			byte[] array = (length == 1) ? new byte[4] : new byte[5];
			bool flag = length != 1;
			if (flag)
			{
				array[4] = (byte)length;
			}
			bool flag2 = address.IndexOf(';') > 0;
			if (flag2)
			{
				string[] array2 = address.Split(new char[]
				{
					';'
				}, StringSplitOptions.RemoveEmptyEntries);
				for (int i = 0; i < array2.Length; i++)
				{
					bool flag3 = array2[i].StartsWith("s=");
					if (flag3)
					{
						value = array2[i].Substring(2);
					}
					else
					{
						Enumerable.ToArray<byte>(Enumerable.Reverse<byte>(array2[i].ToHexBytes())).CopyTo(array, 0);
					}
				}
			}
			else
			{
				Enumerable.ToArray<byte>(Enumerable.Reverse<byte>(address.ToHexBytes())).CopyTo(array, 0);
			}
			return OperateResult.CreateSuccessResult<string, byte[]>(value, array);
		}

		/// <summary>
		/// 根据不同的数据地址，返回实际的数据格式，然后解析出正确的数据
		/// </summary>
		/// <param name="dataArea">数据标识地址，实际的byte数组，地位在前，高位在后</param>
		/// <returns>实际的数据格式信息</returns>
		// Token: 0x06001422 RID: 5154 RVA: 0x00067F70 File Offset: 0x00066170
		public static string GetFormatWithDataArea(byte[] dataArea)
		{
			bool flag = dataArea[3] == 0;
			string result;
			if (flag)
			{
				result = "XXXXXX.XX";
			}
			else
			{
				bool flag2 = dataArea[3] == 1;
				if (flag2)
				{
					result = "XX.XXXX";
				}
				else
				{
					bool flag3 = dataArea[3] == 2 && dataArea[2] == 1;
					if (flag3)
					{
						result = "XXX.X";
					}
					else
					{
						bool flag4 = dataArea[3] == 2 && dataArea[2] == 2;
						if (flag4)
						{
							result = "XXX.XXX";
						}
						else
						{
							bool flag5 = dataArea[3] == 2 && dataArea[2] < 6;
							if (flag5)
							{
								result = "XX.XXXX";
							}
							else
							{
								bool flag6 = dataArea[3] == 2 && dataArea[2] == 6;
								if (flag6)
								{
									result = "X.XXX";
								}
								else
								{
									bool flag7 = dataArea[3] == 2 && dataArea[2] == 7;
									if (flag7)
									{
										result = "XXX.X";
									}
									else
									{
										bool flag8 = dataArea[3] == 2 && dataArea[2] < 128;
										if (flag8)
										{
											result = "XX.XX";
										}
										else
										{
											bool flag9 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 1;
											if (flag9)
											{
												result = "XXX.XXX";
											}
											else
											{
												bool flag10 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 2;
												if (flag10)
												{
													result = "XX.XX";
												}
												else
												{
													bool flag11 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 3;
													if (flag11)
													{
														result = "XX.XXXX";
													}
													else
													{
														bool flag12 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 4;
														if (flag12)
														{
															result = "XX.XXXX";
														}
														else
														{
															bool flag13 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 5;
															if (flag13)
															{
																result = "XX.XXXX";
															}
															else
															{
																bool flag14 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 6;
																if (flag14)
																{
																	result = "XX.XXXX";
																}
																else
																{
																	bool flag15 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 7;
																	if (flag15)
																	{
																		result = "XX.XX";
																	}
																	else
																	{
																		bool flag16 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 8;
																		if (flag16)
																		{
																			result = "XX.XX";
																		}
																		else
																		{
																			bool flag17 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 9;
																			if (flag17)
																			{
																				result = "XX.XX";
																			}
																			else
																			{
																				bool flag18 = dataArea[3] == 2 && dataArea[2] == 128 && dataArea[0] == 10;
																				if (flag18)
																				{
																					result = "XXXXXXXX";
																				}
																				else
																				{
																					bool flag19 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 4 && dataArea[0] <= 2;
																					if (flag19)
																					{
																						result = "XXXXXXXXXXXX";
																					}
																					else
																					{
																						bool flag20 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 4 && dataArea[0] == 9;
																						if (flag20)
																						{
																							result = "XXXXXX";
																						}
																						else
																						{
																							bool flag21 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 4 && dataArea[0] == 10;
																							if (flag21)
																							{
																								result = "XXXXXX";
																							}
																							else
																							{
																								bool flag22 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 5;
																								if (flag22)
																								{
																									result = "XXXX";
																								}
																								else
																								{
																									bool flag23 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 6;
																									if (flag23)
																									{
																										result = "XX";
																									}
																									else
																									{
																										bool flag24 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 7;
																										if (flag24)
																										{
																											result = "XX";
																										}
																										else
																										{
																											bool flag25 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 8;
																											if (flag25)
																											{
																												result = "XX";
																											}
																											else
																											{
																												bool flag26 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 9;
																												if (flag26)
																												{
																													result = "XX";
																												}
																												else
																												{
																													bool flag27 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 13;
																													if (flag27)
																													{
																														result = "X.XXX";
																													}
																													else
																													{
																														bool flag28 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 14 && dataArea[0] < 3;
																														if (flag28)
																														{
																															result = "XX.XXXX";
																														}
																														else
																														{
																															bool flag29 = dataArea[3] == 4 && dataArea[2] == 0 && dataArea[1] == 14;
																															if (flag29)
																															{
																																result = "XXX.X";
																															}
																															else
																															{
																																result = "XXXXXX.XX";
																															}
																														}
																													}
																												}
																											}
																										}
																									}
																								}
																							}
																						}
																					}
																				}
																			}
																		}
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 从用户输入的地址信息中解析出真实的地址及数据标识
		/// </summary>
		/// <param name="address">用户输入的地址信息</param>
		/// <param name="defaultStation">默认的地址域</param>
		/// <returns>解析结果信息</returns>
		// Token: 0x06001423 RID: 5155 RVA: 0x000683C8 File Offset: 0x000665C8
		public static OperateResult<string, int> AnalysisIntegerAddress(string address, string defaultStation)
		{
			OperateResult<string, int> result;
			try
			{
				string value = defaultStation;
				int value2 = 0;
				bool flag = address.IndexOf(';') > 0;
				if (flag)
				{
					string[] array = address.Split(new char[]
					{
						';'
					}, StringSplitOptions.RemoveEmptyEntries);
					for (int i = 0; i < array.Length; i++)
					{
						bool flag2 = array[i].StartsWith("s=");
						if (flag2)
						{
							value = array[i].Substring(2);
						}
						else
						{
							value2 = Convert.ToInt32(array[i]);
						}
					}
				}
				else
				{
					value2 = Convert.ToInt32(address);
				}
				result = OperateResult.CreateSuccessResult<string, int>(value, value2);
			}
			catch (Exception ex)
			{
				result = new OperateResult<string, int>(ex.Message);
			}
			return result;
		}

		/// <summary>
		/// 检查当前的反馈数据信息是否正确
		/// </summary>
		/// <param name="response">从仪表反馈的数据信息</param>
		/// <returns>是否校验成功</returns>
		// Token: 0x06001424 RID: 5156 RVA: 0x00068484 File Offset: 0x00066684
		public static OperateResult CheckResponse(byte[] response)
		{
			bool flag = response.Length < 9;
			OperateResult result;
			if (flag)
			{
				result = new OperateResult(StringResources.Language.ReceiveDataLengthTooShort);
			}
			else
			{
				bool flag2 = (response[8] & 64) == 64;
				if (flag2)
				{
					byte value = response[10];
					bool boolOnIndex = value.GetBoolOnIndex(0);
					if (boolOnIndex)
					{
						result = new OperateResult(StringResources.Language.DLTErrorInfoBit0);
					}
					else
					{
						bool boolOnIndex2 = value.GetBoolOnIndex(1);
						if (boolOnIndex2)
						{
							result = new OperateResult(StringResources.Language.DLTErrorInfoBit1);
						}
						else
						{
							bool boolOnIndex3 = value.GetBoolOnIndex(2);
							if (boolOnIndex3)
							{
								result = new OperateResult(StringResources.Language.DLTErrorInfoBit2);
							}
							else
							{
								bool boolOnIndex4 = value.GetBoolOnIndex(3);
								if (boolOnIndex4)
								{
									result = new OperateResult(StringResources.Language.DLTErrorInfoBit3);
								}
								else
								{
									bool boolOnIndex5 = value.GetBoolOnIndex(4);
									if (boolOnIndex5)
									{
										result = new OperateResult(StringResources.Language.DLTErrorInfoBit4);
									}
									else
									{
										bool boolOnIndex6 = value.GetBoolOnIndex(5);
										if (boolOnIndex6)
										{
											result = new OperateResult(StringResources.Language.DLTErrorInfoBit5);
										}
										else
										{
											bool boolOnIndex7 = value.GetBoolOnIndex(6);
											if (boolOnIndex7)
											{
												result = new OperateResult(StringResources.Language.DLTErrorInfoBit6);
											}
											else
											{
												bool boolOnIndex8 = value.GetBoolOnIndex(7);
												if (boolOnIndex8)
												{
													result = new OperateResult(StringResources.Language.DLTErrorInfoBit7);
												}
												else
												{
													result = OperateResult.CreateSuccessResult();
												}
											}
										}
									}
								}
							}
						}
					}
				}
				else
				{
					result = OperateResult.CreateSuccessResult();
				}
			}
			return result;
		}

		// Token: 0x040004B2 RID: 1202
		private string station = "1";

		// Token: 0x040004B3 RID: 1203
		private string password = "00000000";

		// Token: 0x040004B4 RID: 1204
		private string opCode = "00000000";
	}
}
